-- Ignore useless shit we do not want to accidently target
tblAutoTargetIgnoreList = {
	48266, 	-- "Defias Cannon",
	48284, 	-- "Mining Powder",
	73454,	-- "Manifestation",
	27737, 	-- "Risen Zombie",
	66652, 	-- "Lesser Volatile Energy",
	8317, 	-- "Atal'ai Deathwalker's Spirit",
	9178, 	-- "Burning Spirit",
	29630, 	-- "Fanged Pit Viper",
	40817, 	-- "Shadow of Obsidius"
}
-- Ignore specific npc's with an aura that'll cause us to look like an idiot if we attack it
tblIgnoreNPCwithAura = {
	-- Vanilla
	-- TBC
	-- Northrend
		-- Violet Hold
		[30668] = 60158, 					-- Azure Raider - Magic Reflection 
	-- Cataclysm
		-- Throne of the Tides
		[39616] = 76790, 					-- Naz'Jar Invader Spell Reflection
		[40586] = 75683,					-- Lady Naz'Jar - Waterspout
		-- Blackrock Caverns
		[50284] = 75697,					-- Twilight Zealot - Evolution
		-- Lost City of the Tol'vir
		[44819] = 84589,					-- Siamat - Deflecting Winds
	-- Mists of Pandaria
		[60127] = 115789,					-- Ordos Warbringer - Impervious Shield
		-- Temple of the jade serpent
		[56448] = 106062,					-- Wise Mari - Water Bubble
		[59726] = 113309,					-- Peril - Ultimate Power
		[59051] = 113309,					-- Strife - Ultimate Power
		[56439] = 117665,					-- Sha of Doubt - Bounds of Reality - Immune
		-- Shado-Pan Monastery
		[56747] = 110945,					-- Gu Cloudstrike - Charging Soul - Immune
}
local vNPCID
function AutoTarget()
	if not ccRS.Auto_Target then return end

	-- Grab the NPC's ID
	if UnitExists("target") == 1 then
		vNPCID = ccrNPCID("target")
	end

	-- Clear target
	if UnitIsDead("target")
	or (UnitIsFriend("player", "target") == 1 and UnitCanAttack("player","target") == nil)
	or UnitCreatureType("target") == "Critter"
	or UnitCreatureType("target") == "Wild Pet"
	or ccrIgnoreNPCWithAura("target")
	or tContains(tblAutoTargetIgnoreList, vNPCID) ~= nil
	then
		ClearTarget() 
	end;
	
	-- We already have a target, Exit.
	if UnitExists("target") == 1 then return end
	--

	-- Find the closest target and target
	local vObj = nil
	local vDistance = 40
	local i = 1
	for i = 1, # tblPGetNearbyEnemies do
		local obj = tblPGetNearbyEnemies[i]
		if obj
		and obj:Exists()
		and obj:InLineOfSight()
		and tContains(tblAutoTargetIgnoreList, obj:GetName()) == nil
		and not ccrIgnoreNPCWithAura(obj)
		and WorldToScreen(obj:GetLocation()) ~= nil
		--
		and (
			-- Enemies you are facing has priority
			Player:IsFacing(obj) 
			or
				-- Any enemies just behind you if nothing is infront. Most useful
				-- for melee to quickly turn around
				(
				obj:GetDistance(Player) <= 12
				and
				obj:IsInCombat()
				)
			)
		then
			if ccRS.Auto_Target_In_Combat_Only or (ccRS.Auto_Target_Always_In_Group and (IsInRaid() or IsInGroup())) then
				if obj:GetDistance(Player) < vDistance
				and (obj:IsTappedByPlayer() or (obj:GetTarget():Exists() and obj:GetTarget():GetName() == ccrPlayerName()))
				then
					vObj = obj
					vDistance = obj:GetDistance(Player)
				end
			else
				if obj:GetDistance(Player) < vDistance then
					vObj = obj
					vDistance = obj:GetDistance(Player)
				end
			end
		end
	end

	if vObj ~= nil then vObj:Target() return end

	for i = 1, #Targets do
		local obj = Targets[i]
		ISetAsUnitID(obj, "Internal")
		if obj
		and IExists(obj)
		and GLOS(obj)
		and not tContains(tblAutoTargetIgnoreList, IGetName(obj))
		and not ccrIgnoreNPCWithAura(GetObjectFromGUID(obj))
		and WorldToScreen(IGetLocation(obj))
		and (
			-- Enemies you are facing has priority
			GFacing(Player.GUID, obj)
			or
				-- Any enemies just behind you if nothing is infront. Most useful
				-- for melee to quickly turn around
				(
				GDistance(obj) <= 12
				and
				IIsInCombat(obj)
				)
			)
		then
			if ccRS.Auto_Target_In_Combat_Only then
				if GDistance(obj) < vDistance
				and (UnitIsTappedByPlayer("Internal") or (IExists(IGetTarget(obj)) and IGetTarget(obj) == Player.GUID))
				then
					vObj = obj
					vDistance = GDistance(obj)
				end
			else
				if GDistance(obj) < vDistance then
					vObj = obj
					vDistance = GDistance(obj)
				end
			end
		end
	end

	if vObj ~= nil then GetObjectFromGUID(vObj):Target() return end
end

function IsPointInCone (X, Y, Radians)
	Radians = rad(Radians)
	local PlayerX, PlayerY, PlayerZ, PlayerR = Player:GetLocation();
	local FirstX, FirstY = PlayerX + 10000 * math.cos(PlayerR - (Radians / 2)), PlayerY + 10000 * math.sin(PlayerR - (Radians / 2));
	local SecondX, SecondY = PlayerX + 10000 * math.cos(PlayerR + (Radians / 2)), PlayerY + 10000 * math.sin(PlayerR + (Radians / 2));
	if X >= FirstX
	and X <= SecondX
	and Y >= FirstY
	and Y <= SecondY
	then
		return true
	else
		return false
	end
end

function ccrNPCID(unit)
	unit = ccrUnit(unit)
	if UnitExists(unit) == 1 then
		local vUnitID = tonumber((UnitGUID(unit)):sub(-12, -9), 16)
		if vUnitID then
			return vUnitID
		end
	end
end

function ccrIgnoreNPCWithAura(unit)
	unit = ccrUnit(unit)
	-- Grab the NPC ID from the unit
	local unitid = ccrNPCID(unit)
	-- Does the table contain the NPC ID
	if tblIgnoreNPCwithAura[unitid] ~= nil then
		-- Search the table for the NPC ID and grab the aura to check for
		local vSpellID, k, v
		for k,v in pairs(tblIgnoreNPCwithAura) do
			if k == unitid then
				vSpellID = v
				break
			end
		end
		-- Check vSpellID is not nil
		if vSpellID then
			-- Check the unit for the aura
			local vNPC = GetObjectFromUnitID(unit)
			local name = GetSpellInfo(vSpellID)
			if vNPC
			and vNPC:Exists()
			and vNPC:GetAura(name) ~= nil
			then
				-- Aura found, true = ignore
				return true
			else
				-- Aura not found
				return false
			end
		else
			-- No SpellID retrieved
			return false
		end
	else
		-- NpcID not found
		return false
	end
end